Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Abstract browser and browserType from JS API #910

Merged
merged 7 commits into from
Jun 1, 2023

Conversation

ka3de
Copy link
Collaborator

@ka3de ka3de commented May 30, 2023

Description of changes

This PR abstracts browser and browserType implementations from the JS API. This will allow reducing the boilerplate code typically present in k6 browser scripts in order to initialize and close the browser object. Instead this will be handled transparently for the user.

With this change we are also moving into a tighter integration with k6 by:

  • Enforcing separation of browser scope based on k6 scenarios and iterations.
  • Integrating k6 browser options into k6 scenario definitions.

Checklist

Tasks

Optional tasks

Tasks

@ka3de ka3de added ux breaking PRs that need to be mentioned in the breaking changes section of the release notes labels May 30, 2023
@ka3de ka3de self-assigned this May 30, 2023
@ka3de ka3de added this to the v0.10.0 milestone May 30, 2023
@ka3de ka3de marked this pull request as ready for review May 30, 2023 09:36
@ka3de ka3de requested review from inancgumus and ankur22 May 30, 2023 09:37
Copy link
Collaborator

@ankur22 ankur22 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM 👏

b api.Browser
)

if b, ok = vu.getBrowser(id); ok {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like we're building a new browser object on every iteration, so this would always return nil and false, no? If that's the case then maybe we don't need this check.

Now i see why -- calls to the other browser APIs will retrieve the associated browser object (e.g. i can call newContext multiple times and only the first call to newContext will create the browser object).

browser/registry.go Show resolved Hide resolved
examples/browser_on.js Show resolved Hide resolved
Copy link
Member

@inancgumus inancgumus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overall, it's LGTM, thanks! I believe we need more tests for this change. Especially for reusing of browsers: getOrInitBrowser. It would also be great if we could have tests for the contexts as they were the primary suspects of earlier bugs.

browser/mapping.go Outdated Show resolved Hide resolved
browser/mapping.go Show resolved Hide resolved
chromium/browser_type.go Outdated Show resolved Hide resolved
ka3de added 4 commits May 30, 2023 16:10
BrowserType will no longer be an exposed type through Goja layer,
instead we will handle its functionality from our implementation in the
Go layer.
Adds a new browser registry to be held at the root module level, which
lifecycle spans throughout the whole test run. The registry will store
browser instances per iteration so we can handle their lifecycle from Go
layer based on the iteration lifecycle, which is tight to the VU
context.
Retrieves the scenario name for the given VU context.
This is required in order to build the key for the browsers pool, as the
VU iteration is just a monotonic integer that is shared per scenario.
Therefore, if we don't want to share the browser instance per scenario,
we have to build the pooll key based on the scenario name also.
Because browser is not controlled by explicit JS test code, now every
browser level method will automatically initialize the browser for the
iteration in case it has not been initialized yet in a previous call.
Once the browser is initialized it's stored in the browser registry
indexed by the iteration ID (composed by VUID-scenario-iterationID).
When the iteration ends, signaled by the VU context being done, the
browser is automatically closed and removed from the registry.
ka3de added 3 commits June 1, 2023 10:32
Because we want to handle browser lifecycle automatically from our Go
implementation, we can not build the browser context based on the VU
context, which will be closed at the end of every iteration. That would
result in a race condition between iteration and browser closing
procedure. Instead we will wait for the VU context to be closed and then
from our implementation explicitely call Browser.Close() method.
Previously, the browser implementation components, such as browser,
page, frame... were holding a context inherited from the vu.context
because the browser lifecycle was tight to it. Therefore, we were
passing these contexts when calling k6metrics.PushIfNotDone, as if that
context was done, it meant that the VU context was also done and at the
same time the VU metrics samples channel was closed. With the current
implementation, because the browser, page, frame... contexts do not
inherit from the VU.context, we can not use these contexts when calling
k6metrics.PushIfNotDone, as it is not a guarantee that the vu samples
channel is open, so we should use the VU context directly.
@ka3de ka3de force-pushed the feat/abstract-browser-browserType branch from 5ccd4f9 to 1a91e75 Compare June 1, 2023 08:34
@ka3de
Copy link
Collaborator Author

ka3de commented Jun 1, 2023

Merging this as it is. We will improve it once we have the k6 event system.

@ka3de ka3de merged commit 6b21ec7 into main Jun 1, 2023
@ka3de ka3de deleted the feat/abstract-browser-browserType branch June 1, 2023 14:43
ka3de added a commit that referenced this pull request Jun 1, 2023
A decision was made to no longer expose browser.on method as it
currently only supports 'disconnect' event, and that is non applicable
after the changes made to abstract the browser initialization/closing
procedures from the JS API in
#910.
@ka3de ka3de mentioned this pull request Jun 1, 2023
ka3de added a commit that referenced this pull request Jun 2, 2023
A decision was made to no longer expose browser.on method as it
currently only supports 'disconnect' event, and that is non applicable
after the changes made to abstract the browser initialization/closing
procedures from the JS API in
#910.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking PRs that need to be mentioned in the breaking changes section of the release notes ux
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants